from enum import StrEnum
from sqlalchemy import func
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.ext.mutable import MutableDict
from sqlalchemy.dialects.postgresql import JSONB
from core.file.helpers import get_signed_file_url

from sqlalchemy import func
from models.engine import db
from models.types import StringUUID

class EmojiEmotionMap(StrEnum):
    NEUTRAL = "neutral"
    HAPPY = "happy"
    LAUGHING = "laughing"
    FUNNY = "funny"
    SAD = "sad"
    ANGRY = "angry"
    CRYING = "crying"
    LOVING = "loving"
    EMBARRASSED = "embarrassed"
    SURPRISED = "surprised"
    SHOCKED = "shocked"
    THINKING ="thinking"
    WINKING = "winking"
    COOL = "cool"
    RELAXED = "relaxed"
    DELICIOUS = "delicious"
    KISSY = "kissy"
    CONFIDENT = "confident"
    SLEEPY = "sleepy"
    SILLY = "silly"
    CONFUSED = "confused"
    @staticmethod
    def choices()->list[str]:
        return ["neutral","happy","laughing","funny","sad","angry","crying","loving","embarrassed","surprised","shocked","thinking","winking","cool","relaxed","delicious","kissy","confident","sleepy","silly","confused"]
class EmojiType(StrEnum):
    EMOTION = "emotion"
    LISTEN = "listen"
    NORMAL = "normal"
    @staticmethod
    def choices()->list[str]:
        return ["emotion", "listen", "normal"]

class RobEmoji(db.Model):
    __tablename__ = "rob_emoji"
    __table_args__ = (
        db.PrimaryKeyConstraint('id', name='rob_emoji_pk'),
        db.Index('idx_rob_emoji_tenant', 'tenant_id'),
    )
    id: Mapped[str] = mapped_column(
        StringUUID, server_default=db.text("uuid_generate_v4()"),)
    tenant_id = db.Column(StringUUID, nullable=False)
    name = db.Column(db.String(128), nullable=False, comment="名称")
    descrip = db.Column(db.String(512), nullable=False, comment="说明描述")
    emo_code = db.Column(db.String(16), nullable=False, comment="表情code")
    emo_type = db.Column(db.String(16), nullable=False, comment="表情类型")
    emo_map = db.Column(MutableDict.as_mutable(JSONB),nullable=True,server_default=db.text("'{}'::jsonb"), comment="表情映射")
    file_id = db.Column(StringUUID, nullable=True, comment="表情文件ID")
    file_url = db.Column(db.String(512), nullable=True, comment="表情文件URL")
    price = db.Column(db.Integer, nullable=False, default=0, comment="价格/分")
    created_at = db.Column(db.DateTime, nullable=False,
                           server_default=func.current_timestamp(), comment="创建时间")
    created_by = db.Column(StringUUID, nullable=False, comment="创建人")
    updated_at = db.Column(db.DateTime, nullable=True,
                           server_default=func.current_timestamp())
    updated_by = db.Column(StringUUID, nullable=True,)

    @property
    def emoji_preview_url(self) -> str:
        if self.file_url:
            return self.file_url
        elif self.file_id:
            return get_signed_file_url(self.file_id)
        return ""

    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "name": self.name,
            "emo_code": self.emo_code,
            "url": self.emoji_preview_url,
        }
    
    def to_server_init_dict(self)->dict:
        return {
            "code":self.emo_code,
            "name":self.name,
            "descrip":self.descrip,
        }
    
    @property
    def emoji_map(self)->list[str]:
        if self.emo_map and "items" in self.emo_map:
            return self.emo_map["items"]
        return []


class RobEmoPackMap(db.Model):
    __tablename__ = "rob_emoji_pack_map"
    __table_args__ = (
        db.PrimaryKeyConstraint('emoji_id', 'pack_id',
                                name='idx_rob_emo_pack_map_pk'),
        db.Index('idx_rob_emo_pack_map_pack', 'pack_id'),
    )
    emoji_id = db.Column(StringUUID, nullable=False, comment="表情ID")
    pack_id = db.Column(StringUUID, nullable=False, comment="表情包ID")
    created_at = db.Column(db.DateTime, nullable=False,
                           server_default=func.current_timestamp(), comment="创建时间")
    created_by = db.Column(StringUUID, nullable=False, comment="创建人")


class RobEmojiPack(db.Model):
    __tablename__ = "rob_emoji_pack"
    __table_args__ = (
        db.PrimaryKeyConstraint('id', name='rob_emoji_pack_pk'),
        db.Index('idx_rob_emoji_pack_tenant', 'tenant_id'),
    )
    id: Mapped[str] = mapped_column(
        StringUUID, server_default=db.text("uuid_generate_v4()"),)
    tenant_id = db.Column(StringUUID, nullable=False)
    agent_id = db.Column(StringUUID, nullable=False, comment="表情判别智能体id")
    name = db.Column(db.String(128), nullable=False, comment="名称")
    descrip = db.Column(db.String(512), nullable=False, comment="说明描述")
    price = db.Column(db.Integer, nullable=False, default=0, comment="价格/分")
    created_at = db.Column(db.DateTime, nullable=False,
                           server_default=func.current_timestamp(), comment="创建时间")
    created_by = db.Column(StringUUID, nullable=False, comment="创建人")
    updated_at = db.Column(db.DateTime, nullable=True,
                           server_default=func.current_timestamp())
    updated_by = db.Column(StringUUID, nullable=True,)

    def get_emojis(self) -> list[RobEmoji]:
        return db.session.query(RobEmoji).join(RobEmoPackMap, RobEmoji.id == RobEmoPackMap.emoji_id).filter(RobEmoPackMap.pack_id == self.id).all()

    @property
    def Price(self) -> float:
        return float(self.price)*(1.0/1000.0)
    
    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "tenant_id": self.tenant_id,
            "name": self.name,
            "emojis": [emoji.to_dict() for emoji in self.get_emojis()],
        }
    
    def to_server_init_dict(self)->dict:
        emoji_map = {}
        emojis_params = []
        for emoji in self.get_emojis():
            emotions = emoji.emoji_map
            for emotion in emotions:
                emoji_map[emotion] = emoji.emo_code
            emojis_params.append(emoji.to_server_init_dict())
        return {
            "id": self.id,
            "name": self.name,
            "agent_id": self.agent_id,
            "emojis_params": emojis_params,
            "emoji_map": emoji_map,
        }


class RobEmoPackHVERMap(db.Model):
    __tablename__ = "rob_emoji_pack_hver_map"
    __table_args__ = (
        db.PrimaryKeyConstraint('pack_id', 'hver',
                                name='idx_rob_emoji_pack_hver_map_pk'),
        db.Index('idx_rob_emo_pack_hver_map_hver', 'hver'),
    )
    hver = db.Column(db.String(32), nullable=False, comment="硬件版本")
    pack_id = db.Column(StringUUID, nullable=False, comment="表情包ID")
    created_at = db.Column(db.DateTime, nullable=False,
                           server_default=func.current_timestamp(), comment="创建时间")
    created_by = db.Column(StringUUID, nullable=False, comment="创建人")

    @property
    def emoji_packs(self) -> list[RobEmojiPack]:
        return db.session.query(RobEmojiPack).filter(RobEmojiPack.id == self.pack_id).all()
